package com.nulldev.util.networking.async2;

import java.util.Arrays;

public final class ByteArrayBuilder {
	private byte[] fBytes;
	private final Object fLock;

	public ByteArrayBuilder() {
		this.fLock = new Object();
		this.fBytes = new byte[0];
	}

	/**
	 * Append data to ByteArrayBuilder
	 *
	 * @param data is the byte[] array to append
	 */
	public void append(final byte[] data) {
		synchronized (this.fLock) {
			final byte[] newArray = new byte[this.fBytes.length + data.length];
			System.arraycopy(fBytes, 0, newArray, 0, this.fBytes.length);
			System.arraycopy(data, 0, newArray, this.fBytes.length, data.length);
			this.fBytes = newArray;
		}
	}

	public int indexOf(final byte[] subArray) {
		synchronized (this.fLock) {
			int i = 0;
			int subArrayLength = subArray.length;
			for (i = 0; i < this.fBytes.length; i++) {
				byte[] arrayToCompare = Arrays.copyOfRange(this.fBytes, i, i + subArrayLength);
				if (Arrays.equals(arrayToCompare, subArray)) {
					return i;
				}
			}
			return -1;
		}
	}

	public void delete(final int indexFrom, final int indexTo) {
		synchronized (this.fLock) {
			final byte[] firstPart = Arrays.copyOfRange(this.fBytes, 0, indexFrom);
			final byte[] secondPart = Arrays.copyOfRange(this.fBytes, indexTo, this.fBytes.length);
			final byte[] C = new byte[firstPart.length + secondPart.length];
			System.arraycopy(firstPart, 0, C, 0, firstPart.length);
			System.arraycopy(secondPart, 0, C, firstPart.length, secondPart.length);
			this.fBytes = C;
		}
	}

	public byte[] subList(final int fromIndex, final int toIndex) {
		synchronized (this.fLock) {
			return Arrays.copyOfRange(this.fBytes, fromIndex, toIndex);
		}
	}

	public void dispose() {
		synchronized (this.fLock) {
			this.fBytes = new byte[0];
		}
	}
}
